/**
 * api信息框  所有的方法都支持modal完整的参数
 * 用于支持插槽的props字段为 $slots Object {default:h()|String|ELEment|VNode,slotName2:...}
 * 额外支持添加一个class字段用于区分
 * @Author 木木 175588516@qq.com
 * @Description modal扩展api调用
 * @Date 2022/8/1
 * @Example this.$toast(params) this.$toast.loading(params)   Toast(params)   Toast.loading(params)  ...
 */
import { createVNode, render,h } from 'vue'
import modal from './modal.vue'
import Loading from './Loading.vue'
const propsFilter=(props,options)=>{
	if(options && typeof options == 'string') props.message=options
	if(Object.prototype.toString.call(options)=='[object Object]')
	props={
		...props,
		...options
	};
	return props;
}

const Toast = (options)=>{
	let props={
		footer:{show:false},
		size:'sm',
		showClose:false,
		type:'info',
		duration:3000,
		show:true,
		escClosable:false,
		mask:false,
		place:"center",
		'onUpdate:show':val => vm.component.props.show = val,
	};
	props=propsFilter(props,options);
	let { type, duration, $slots} = props;
	delete props.type;
	delete props.duration;
	delete props.$slots;
	if(props.message)
	switch(type){
		case 'loading':
			props.message=`<div class="mp-15">
				<i class="glyphicon glyphicon-repeat rotate mm-r-10"></i>
				<!-- ${props.message} -->
			</div>`;
			props.message=''
		break;
		case 'info':
			props.message=`<div class="mp-15">
				<i class="glyphicon glyphicon-exclamation-sign text-primary mm-r-10"></i>
				<span class="">${props.message}</span>
			</div>`;
		break;
		case 'err':
			props.message=`<div class="mp-15">
				<i class="glyphicon glyphicon-remove-circle text-danger mm-r-10"></i>
				<span class="text-danger">${props.message}</span>
			</div>`;
		break;
		case 'warn':
			props.message=`<div class="mp-15">
				<i class="glyphicon glyphicon-alert text-warning mm-r-10"></i>
				<span class="">${props.message}</span>
			</div>`;
		break;case 'success':
			props.message=`<div class="mp-15">
				<i class="glyphicon glyphicon-ok text-success mm-r-10"></i>
				<span class="">${props.message}</span>
			</div>`;
		break;
		case 'confirm':
			props.message=`<div class="mp-15">
				<span class="">${props.message}</span>
			</div>`;
		break;
	}
	const container = document.createElement('div')
	if(props.class) container.classList.add(props.class)
    const vm = type == 'loading' ? createVNode(Loading, props,$slots) : createVNode(modal, props,$slots)
    render(vm, container)
    document.body.appendChild(container)
	// console.log(vm)
	if(duration && !isNaN(duration) && duration>0) setTimeout(()=>{ destory() }, parseInt(duration)||2000)
	let destory=()=>{
		vm.component.props.show=false;
		setTimeout(()=>{
			try {
				render(null, container)
				document.body.removeChild(container)
			} catch (error) {
				console.warn('请注意，toast组件被销毁时，可能已经被移除，请检查代码运行逻辑。',error)
			}
		},300);
	}
	let update=(newVal)=>{
		newVal = propsFilter({},newVal);
		for (const key in newVal)
			if (Object.hasOwnProperty.call(newVal, key)) vm.component.props[key] = newVal[key];
	}
	return {
		destory,
		update,
		vm
	}
}
// 加载中
Toast.loading=(options)=>{
	let props={
		type:'loading',
		duration:0,
		mask:0.01,
	};
	props=propsFilter(props,options);
	return Toast(props)
}
// 信息
Toast.info=(options)=>{
	let props={
		type:'info',
		duration:3000
	};
	props=propsFilter(props,options);
	return Toast(props)
}
Toast.msg=Toast.info;//别名
Toast.message=Toast.info;//别名
// 错误
Toast.error=(options)=>{
	let props={
		type:'err',
		duration:3000
	};
	props=propsFilter(props,options);
	return Toast(props)
}
Toast.err = Toast.error
// 警告
Toast.warn=(options)=>{
	let props={
		type:'warn',
		duration:3000
	};
	props=propsFilter(props,options);
	return Toast(props)
}
// 成功
Toast.success=(options)=>{
	let props={
		type:'success',
		duration:3000,
	};
	props=propsFilter(props,options);
	return Toast(props)
}
// 确认
Toast.confirm=(options)=>{
	let props={
		type:'confirm',
		duration:0,
		footer:undefined,
		escClosable:true,
		mask:true,
		size:{
			minWidth:'300px',
			maxWidth:'430px',
		},
	};
	props=propsFilter(props,options);
	if(!options.onConfirm && !options.cancel){
		return new Promise(resolve=>{
			let confirm = Toast({
				...props,
				onConfirm:()=>{
					confirm.destory()
					resolve(true)
				},
				onCancel:()=>{
					resolve(false)
				}
			});
		})
	}else{
		return Toast(props)
	}
}
Toast.model=(options)=>{
	let props={
		type:'model',
		duration:0,
		footer:undefined,
		escClosable:true,
	};
	props=propsFilter(props,options);
	if(!options.onConfirm && !options.cancel){
		return new Promise(resolve=>{
			let confirm = Toast({
				...props,
				onConfirm:()=>{
					confirm.destory()
					resolve(true)
				},
				onCancel:()=>{
					resolve(false)
				}
			});
		})
	}else{
		return Toast(props)
	}
}
Toast.install=(Vue)=>{
	Vue.config.globalProperties.$toast=Toast
}
export default Toast
